Elastic Observability Uptime 中 Synthetic Monitor 功能的推出,主要是針對使用者體驗 (User Experience) 的角度所發展出來的功能,設計的目的是『能夠在使用者遇到問題之前,先發現他們可能將遇到的問題』,因此透過分析使用者存取網頁的情境,產生並模擬出這些情境的操作步驟,並且將這些步驟記錄下來,當作監控的依據,同時在發生異常時,也因為保留了這些步驟的歷程資料,能夠更即時的協助開發與運維的人員解決問題。
注意:Synthetic Monitor 是在 Elastic Observability 7.10 版發佈時推出的,推出的時間是在 2020 年 11 月,寫這篇文章時,已經到 Elastic Observability 7.14 版了,不過 Synthetic 還是在實驗 (Experimental) 的階段,也就是官方不建議直接使用在 Production 上,如果要使用的話,未來正式版推出時不見得會確保向前相容,這部份的風險要自己承擔。
Elastic Synthetic 底層是使用 Playwright 這個 Node.js 的函式庫,透過 Playwright 能使用簡單的 API 來操作 Chromium, Firefox, Webkit 等瀏覽器的核心,進而模擬出使用者操作瀏覽器的行為,因此 @elastic/synthetics
也就是使用 javascript 開發的函式庫,並且與 Heartbeat 所延伸開發出來的 Heartbeat synthetics module
進行整合,讓我們能夠直接使用 Heartbeat 來透過 @elastic/synthetics
執行指定的腳本,並且將這些結果透過 Heartbeat 記錄回 Elasticsearch。
Elastic Observability 同時也在 Kibana 的 Uptime app 之中深度的整合並支援 Synthetic Monitor,讓透過 Synthetic Monitor 記錄的資訊,也就能和其他 Heartbeat 所接收到的資訊一樣,可以直接在單一的入口網站 Uptime 能查看結果、也能使用 Alert 機制在異常的時候主動通知我們。
這邊建議大家參考 官方文件 Synthetics Quickstart [2] 來參考如何進行配置及快速上手,主要的概念我這邊整理了一下,協助大家理解,但細節的請參考官方文件。
由於 Synthetic 的使用環境較複雜,因此官方建議使用 Docker 的環境來運作,不過在開發的階段,我們可以直接使用本地端來執行。
注意:由於官方提供的 Docker Image 目前喬叔使用 Apple M1 CPU 無法正常使用,應該是 Synthetic 裡所使用到的套件有支援度的問題,所以在花了許多時間嘗試卻失敗之後,我在使用 Docker 環境執行 Synthetic 的時候是使用 Windows + Linux VM 的環境來運作。
要在學會執行的話,最簡單的方式就是直接將官方 Synthetic Github 的專案 Clone 下來,學習他怎麼做:
git clone https://github.com/elastic/synthetics/tree/master/
在裡面的 examples
路徑下,分別有
docker
:使用 run.sh
可以運作一個 docker container 並執行路徑下的 heartbeat.docker.yml
所定義的腳本,或是使用 bash.sh
會運作 docker container 並且進入 docker 環境,可以直接在裡面執行要測試的腳本。e-commerce
:這是一個較完整的電商示範網站,裡面也有一些較完整的腳本,不過目前電商網站掛了,要跑的話要自己架起來。in-line
:裡面有幾個簡單的腳本,可以直接透過下方所教的執行 Synthetic 的方法來使用。todos
:這是一個簡單的 ToDo 的 App,裡面也有包含兩種執行 Synthetic 方式的實作,可以供參考。執行的方式分為兩種:
@elastic/synthetic
執行可以透過
npm install @elastic/synthetic
的方式安裝,或是在上面提到的 example 的專案中,透過 npm install
來安裝 package.json
裡面指定好的相依的套件。
再來可以透過
npx @elastic/synthetics .
執行當下目錄的所有的 .journey.ts
或是 .journey.js
的腳本。
或是透過以下的指定,使用 inline
的方式執行 xxx.js
裡面所定義的腳本。
cat xxx.js | npx @elastic/synthetics --inline
請注意!這種方式只是單純的執行腳本的結果,並不會把結果傳送到 Elasticsearch 去,也就是在 Uptime 裡是看不到結果的。
Heartbeat
執行若我們要透過 Heartbeat 執行時,要先定義好 heartbeat.yml
的設定,裡面可以使用兩種執行的方式 - inline
的腳本以及 指定腳本檔案下載路徑
的方式,例如 todos
的 examples 裡面的 heartbeat.yml
就有包含這兩種的例子。
heartbeat.monitors:
- type: browser
id: elastic-website
name: Elastic website
schedule: "@every 1m"
source:
inline:
script: |-
step("load homepage", async () => {
await page.goto('https://www.elastic.co');
});
step("hover over products menu", async () => {
await page.hover('css=[data-nav-item=products]');
});
- name: Todos
id: todos
type: browser
schedule: "@every 1m"
source:
zip_url:
url: "https://github.com/elastic/synthetics/archive/refs/heads/master.zip"
folder: "examples/todos"
username: ""
password: ""
要編寫 Synthetic 腳本,主要是要了解 Playwright 的使用方式,主要編寫測試時會用到的語法如下:
journey
:用來測試一個主要的功能情境但擁有多個分散步驟的案例。step
:一個 journey
裡面所執行的某個驟步,可以是開啟網頁、滑動到某個元件、點選某個按鈕…等。beforeAll
、before
、afterAll
、after
:這些分別用來定義執行 journey
之前、或之後要執行的動作。一個 journey
裡面包含幾個重要的元件:
browser
:瀏覽器物件,瀏覽器層級的功能會在這邊可以使用。page
:頁面,可跳轉頁面到指定的 URL,或是執行 screenshot,或是在某些頁面的事件事做事。context
:browser
的某個 context,當有多個使用瀏覽器的情境、並且不希望共用 cookie, cache 時,就會建立多個 context。params
:使用者定義的參數。例如 examples e-commerce
裡面的一段範例:
journey({ name: 'Delete cart items', tags: ['cart'] }, ({ page, params }) => {
navigateToProductDetail(page, params);
step('Add items to cart', async () => {
await page.selectOption('select[name="quantity"]', '2');
await Promise.all([
page.waitForNavigation({
url: /cart/,
waitUntil: 'networkidle',
}),
page.click('text=Add to Cart'),
]);
});
step('empty cart items', async () => {
const headline = await page.$('.container h3');
expect(await headline.textContent()).toContain(
'1 items in your Shopping Cart'
);
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle' }),
page.click('text=Empty cart'),
]);
});
step('verify empty shopping cart', async () => {
await Promise.all([
page.waitForNavigation({ url: /cart/, waitUntil: 'networkidle' }),
page.click('text=View Cart'),
]);
await page.waitForSelector('.container');
const headline = await page.$('.container h3');
expect(await headline.textContent()).toContain(
'Your shopping cart is empty'
);
});
});
我們回到 Kibana 的 Uptime 主畫面,在這個畫面之中,我們可以看到有兩個 Browser
類型的 Monitor,這個就是使用 @elastic/synthetic
所收集到的資料,也就是專門是以使用者行為模擬出的前端網頁操作情境。
接下來我們點選其中一個 13th iTHome Ironeman OneDoggo - inline 的 Monitor,觀看裡面的記錄細節,與一般的 Monitor 的結果差不多,不過可以發現在 History 的部份,多了畫面的截圖。
journey
結果點選 History 當中的某一筆記錄之後,我們可以看到這個 journey
的結果,總共包含三個部份:
step
的執行細節任何一個 journey
的 step
展開後,都可以看到這個 step
的執行語法與執行結果,甚至 Console output 也會記錄起來,對於要記錄資訊查問題,非常的方便。
step
檢視效能的分析點選某一個 step
的 performance breakdown
之後,可以查看這個頁面在載入時的細節。
點選任何一個資源請求,可以查看當時完整的細節資訊,雖然不像 Dev Tools 這麼強大,但這是定期依照我們要的情境所記錄下來的資訊,能夠還原當時發生了什麼事,是不是某些資源當下載入的時間超過預期。
這個 Synthetic 的功能實在是讓人很驚豔,本來想順便做一個監控團員們大家有沒有準時發文的 journey
,但後來發現我最近花在寫鐵人賽文章的時間太久了,我家的狗一直關在家心情不是很好,所以只好收手,好好當個狗奴才去遛狗,期待 Elastic 正式推出 Synthetics Monitor 的功能!
查看最新 Elasticsearch 或是 Elastic Stack 教育訓練資訊: https://training.onedoggo.com
歡迎追蹤我的 FB 粉絲頁: 喬叔 - Elastic Stack 技術交流
不論是技術分享的文章、公開線上分享、或是實體課程資訊,都會在粉絲頁通知大家哦!